#ifndef ANIMATIONSYSTEM_H
#define ANIMATIONSYSTEM_H
#pragma once

#include <vector>

#include "EDFrame.h"

////////////////////////////////////////////////////////////////
// Stores the state of the animation at a given time
////////////////////////////////////////////////////////////////
struct KeyFrame
{
	// The time this keyframe happens at
	float m_fKeyTime;

	// The transforms for this keyframe
	std::vector< EDFrame > m_vTransformFrames;
};

////////////////////////////////////////////////////////////////
// Stores the Mesh data
////////////////////////////////////////////////////////////////
class Mesh
{
	friend class Model;
private:

	std::vector<float3>			m_vVertices;
	std::vector<float3>			m_vNormals;
	std::vector<unsigned int>	m_vIndices;
	std::vector< std::vector<float> > m_vWeights;

public:
	std::vector<float3>			&GetVertices(void)	{ return m_vVertices; }
	std::vector<float3>			&GetNormals(void)	{ return m_vNormals; }
	std::vector<unsigned int>	&GetIndices(void)	{ return m_vIndices; }
	std::vector< std::vector<float> > &GetWeights(void){ return m_vWeights; }
};

////////////////////////////////////////////////////////////////
// Stores the Multiple Meshes of a Model
////////////////////////////////////////////////////////////////
class Model
{
private:
	std::vector<Mesh>	m_vMeshes;
public:
	////////////////////////////////////////////////////////////////
	// Loads a mesh from a file
	//
	// Parameters
	// string fileName - the name of the mesh file
	////////////////////////////////////////////////////////////////
	void LoadMeshesFromFile(std::string fileName);

	std::vector<Mesh>	&GetMeshes(void) { return m_vMeshes; }
};

////////////////////////////////////////////////////////////////
// Stores the animation data
////////////////////////////////////////////////////////////////
class Animation
{	friend class Interpolator;
private:
	float m_fDuration;

	std::vector< KeyFrame > m_vKeyFrames;
public:
	Animation(void){ }
	~Animation(void){ }

	////////////////////////////////////////////////////////////////
	// Loads the animation from a file
	//
	// Parameters
	// string fileName - the name of the animation file
	////////////////////////////////////////////////////////////////
	void LoadFromFile(std::string fileName);

	std::vector< KeyFrame > &GetKeyFrames(void){ return m_vKeyFrames; }
	float GetDuration(void){ return m_fDuration; }
};

class Interpolator
{
private:
	const Animation *m_pAnimation;

	KeyFrame m_CurrentKeyFrame;

	float m_fCurrentTime;

	// Storing some angles for procedural animation...
	float m_fAngleTot;
	float m_fAngle;
public:

	Interpolator(void) : m_pAnimation(0), m_fAngleTot(0.0f), m_fAngle(0.001f){ }
	~Interpolator(void){ }

	////////////////////////////////////////////////////////////////
	// Attaches an animation to the interpolator
	//
	// Parameters
	// const Animation *inAnimation - the animation to attach to
	////////////////////////////////////////////////////////////////
	void SetAnimation(const Animation *inAnimation);

	////////////////////////////////////////////////////////////////
	// Adds time to the interpolator
	//
	// Parameters
	// float t - the time to add
	////////////////////////////////////////////////////////////////
	void AddTime(float t) {  }

	////////////////////////////////////////////////////////////////
	// Sets the interpolators time
	//
	// Parameters
	// float t - the time to set to
	////////////////////////////////////////////////////////////////
	void SetTime(float t) {  }

	////////////////////////////////////////////////////////////////
	// Interpolates between the animations key-frames based on the 
	// interolator's current time
	////////////////////////////////////////////////////////////////
	void Process(void);

	KeyFrame &GetCurrentKeyFrame(void){ return m_CurrentKeyFrame; }
};

#endif